#include "cqtopencvviewergl.h"

CQtOpenCVViewerGl::CQtOpenCVViewerGl(QWidget *parent) :
    QGLWidget(parent)
{
   mSceneChanged = false;
   mBgColor      = QColor::fromRgb(150,150,150);

   mOutH = 0;
   mOutW = 0;
   mImratio = 4.0f/ 3.0f; //Default image ratio

   mPosX = 0;
   mPosY = 0;

   drawCenterSquareLine = false;
   isStaticView         = false;

   messageBox.setWindowTitle("PiQrCode Reader Says:");
   messageBox.setText("QrCode Decoded!");
   messageBox.setIcon(QMessageBox::Information);
   messageBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);

   startTimer(500); // start the animation

}

void
CQtOpenCVViewerGl::initializeGL()
{
    makeCurrent();
    qglClearColor(mBgColor.light());
    //glOrtho (0, 400, 0, 400, 0, 1); //to draw image in the center of the area
}

void
CQtOpenCVViewerGl::resizeGL(int w, int h)
{
    makeCurrent();

    glViewport (0,0, (GLint) h, (GLint) w);

    glMatrixMode (GL_PROJECTION);
    glLoadIdentity();


    glOrtho (0, w, 0, h, 0, 1); //to draw image in the center of the area

    glMatrixMode (GL_MODELVIEW);

    // -----> scaled Image Sizes
    mOutH = w / mImratio;
    mOutW = w;

    if (mOutH > h) {

        mOutW = h * mImratio;
        mOutH = h;

    }

    emit imageSizeChanges (mOutW, mOutH);
    // <------ scaled Image Sizes

    mPosX = (w - mOutW) / 2;
    mPosY = (h - mOutH) / 2;

    mSceneChanged = true;

    updateScene();


}

void
CQtOpenCVViewerGl::updateScene()
{
    if (mSceneChanged && this->isVisible()) {
        updateGL();
    }
}

void
CQtOpenCVViewerGl::paintGL()
{
    makeCurrent();

    if (!mSceneChanged)
        return;

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    renderImage();

    if (!isStaticView)
        paintCentralSquare(mRenderQtImg.width());

    mSceneChanged = false;
}

void
CQtOpenCVViewerGl::renderImage()
{
    makeCurrent();

    glClear (GL_COLOR_BUFFER_BIT);

    if (!mRenderQtImg.isNull()) {

        glLoadIdentity ();

        QImage image; // the image rendered

        glPushMatrix();
        {
            int imW = mRenderQtImg.width();
            int imH = mRenderQtImg.height();

            //the image is to resized to fit the widget
            if (imW != this->size().width() && imH != this->size().height()) {

                QSize q = (isStaticView)? QSize(355, 355) : QSize(mOutW, mOutH);

                image = mRenderQtImg.scaled ( q,
                                              Qt::IgnoreAspectRatio,
                                              Qt::SmoothTransformation);
             } else {

                image = mRenderQtImg;

             }

            // -----> centering image in draw area
            glRasterPos2i (mPosX, mPosY);
            // <----- centering image in draw area

            imW = image.width();
            imH = image.height();

            glDrawPixels (imW, imH, GL_RGBA, GL_UNSIGNED_BYTE, image.bits());

        }
        glPopMatrix ();

        //end
        glFlush ();

    }
}

bool
CQtOpenCVViewerGl::showImage(cv::Mat image)
{
    image.copyTo (mOriginImage);

    mImratio = (float) image.cols / (float) image.rows;

    if ( mOriginImage.channels() == 3) {

        mRenderQtImg = QImage ( (const unsigned char*) (mOriginImage.data),
                                mOriginImage.cols, mOriginImage.rows,
                                mOriginImage.step, QImage::Format_RGB888
                              ).rgbSwapped();

    } else if (mOriginImage.channels() == 1) {

        mRenderQtImg = QImage ( (const unsigned char*) (mOriginImage.data),
                                mOriginImage.cols, mOriginImage.rows,
                                mOriginImage.step, QImage::Format_RGB888
                              );

    } else {
        return false;
    }

    string data = reader.readQrCode(&mRenderQtImg);


    if (data != "")
    {
        string details =  reader.getCanvas().showLog();

        QString QrCodevalue = QString::fromAscii(data.c_str());
        QString QrCodeDetails = QString::fromAscii(details.c_str());

        messageBox.setInformativeText(QrCodevalue);
        messageBox.setDetailedText(QrCodeDetails);

        messageBox.show();

        if (isStaticView)
            cv::imshow("Original", mOriginImage);
        else
        {
            cv::Mat capture = cv::Mat(mRenderQtImg.height(), mRenderQtImg.width(), CV_8UC3, mRenderQtImg.scanLine(0));
            cv::imshow("Captura", capture);
        }
    }



    mRenderQtImg = QGLWidget::convertToGLFormat(mRenderQtImg);

    mSceneChanged = true;

    updateScene();

    return true;
}

void
CQtOpenCVViewerGl::paintCentralSquare(int imageWidth)
{
    makeCurrent();

    int x1, y1, x2, y2;
    x1 = y1 = 275;
    x2 = y2 = 125;


    if (imageWidth > 0) {
        glLineWidth(3);
        glBegin(GL_LINE_LOOP);
            glColor3f(1, 1, 1);
            glLineWidth(6);
            glVertex2f(x1, y1); glVertex2f(x2, y1); glVertex2f(x2, y2); glVertex2f(x1, y2);
        glEnd();

        if (drawCenterSquareLine) {
            glLineWidth(2);
            glBegin(GL_LINES);
                glColor3f(0.7, 0.2, 0.2);
                glVertex2f(x1,(x1+x2)/2); glVertex2f(x2,(x1+x2)/2);
            glEnd();
        }
    }
}
void CQtOpenCVViewerGl::timerEvent(QTimerEvent *)
{
    drawCenterSquareLine = !drawCenterSquareLine;
}

void CQtOpenCVViewerGl::setStaticView(bool isStatic)
{
    isStaticView = isStatic;
}
